package se.liu.oschi129.world.model;

import se.liu.oschi129.world.objects.WorldObject;

/**
 * This class is a view used to focus the screen on a certain position in the world.
 * The view is also accessed by the ViewController in order to calculate drawing
 * translation in the component relative to the world. 
 * 
 * @author oschi129
 */
public class WorldView implements Cloneable {

	// View settings
	private int viewX, viewY, viewWidth, viewHeight;
	
	// The object to follow
	private WorldObject followObject;
	
	// How the object should be followed
	private boolean followHorizontal, followVertical;
	
	/**
	 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	 * - - - - - - - - - - - - Constructors - - - - - - - - - - - 
	 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	 */
	
	public WorldView(int viewX, int viewY, int viewWidth,int viewHeight, WorldObject followObject, boolean followHorizontal, boolean followVertical) {
		setViewX(viewX);
		setViewY(viewY);
		setViewWidth(viewWidth);
		setViewHeight(viewHeight);
		setFollowObject(followObject);
		setFollowHorizontal(followHorizontal);
		setFollowVertical(followVertical);
	}
	
	public WorldView(int viewWidth, int viewHeight) {
		this(0,0,viewWidth,viewHeight,null,false,false);
	}
	
	public WorldView(int viewWidth, int viewHeight, WorldObject followObject) {
		this(0,0,viewWidth,viewHeight,followObject,true,true);
	}
	
	public WorldView(int viewWidth, int viewHeight, WorldObject followObject, boolean followHorizontal, boolean followVertical) {
		this(0,0,viewWidth,viewHeight,followObject,followHorizontal, followVertical);
	}
	
	/**
	 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	 * - - - - - - - - - - - Public methods - - - - - - - - - - 
	 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	 */
	
	/** Returns a clone of the view */
	public WorldView clone() {
		return new WorldView(getViewX(), getViewY(), getViewWidth(), getViewHeight(), getFollowObject(), getFollowHorizontal(), getFollowVertical());
	}
	
	/** Returns the x position of the view */
	public int getViewX() {
		return viewX;
	}
	
	/** Sets the x position of the view */
	public void setViewX(int viewX) {
		this.viewX = viewX;
	}
	
	/** Returns the y position of the view */
	public int getViewY() {
		return viewY;
	}
	
	/** Sets the y position of the view */
	public void setViewY(int viewY) {
		this.viewY = viewY;
	}
	
	/** Returns the width of the view */
	public int getViewWidth() {
		return viewWidth;
	}
	
	/** Sets the width of the view */
	public void setViewWidth(int viewWidth) {
		this.viewWidth = viewWidth;
	}
	
	/** Returns the height of the view */
	public int getViewHeight() {
		return viewHeight;
	}
	
	/** Sets the height of the view */
	public void setViewHeight(int viewHeight) {
		this.viewHeight = viewHeight;
	}
	
	/** Returns true if the view follows the targeted object horizontally */
	public boolean getFollowHorizontal() {
		return followHorizontal;
	}
	
	/** Sets whatever the view should be following the target horizontally */
	public void setFollowHorizontal(boolean followHorizontal) {
		this.followHorizontal = followHorizontal;
	}
	
	/** Returns true if the view follows the targeted object vertically */
	public boolean getFollowVertical() {
		return followVertical;
	}
	
	/** Sets whatever the view should be following the target vertically */
	public void setFollowVertical(boolean followVertical) {
		this.followVertical = followVertical;
	}
	
	/** Returns the followed object */
	public WorldObject getFollowObject() {
		return followObject;
	}
	
	/** Sets the followed object */
	public void setFollowObject(WorldObject followObject) {
		this.followObject = followObject;
	}
	
	/** Focusing the view onto the followed object */
	public void update(World world) {
		if (getFollowObject() != null) {
			if (getFollowHorizontal())
				setViewX((int) Math.min(Math.max(0, getFollowObject().getX()-getViewWidth()/2), world.getWidth() - getViewWidth()));
			if (getFollowVertical())
				setViewY((int) Math.min(Math.max(0, getFollowObject().getY()-getViewHeight()/2), world.getHeight() - getViewHeight()));
		}
	}
	
}
